#include <stdio.h>

#include <winsock2.h>

#include <assert.h>

#include "socket.h"
#include "key_value.h"
#include "test.h"


void env_init(void)
{
	//init env
	printf("env_init\n");
	//startup a new thread
	
	/*start up monkey runner by windows bat in the new thread*/
	//system("service.bat");
	
	/*init socket*/
	if(!socket_init())
	{
		//TODO:: clean up env
		env_deinit();
	}

	/*install apk*/
   install_apk("PhoneTest3.apk");
   adbcmd("adb shell am broadcast -a NotifyServiceStop");
   adbcmd("adb forward tcp:8003 tcp:3023");
   adbcmd("adb shell am broadcast -a NotifyServiceStart");	
}

void env_deinit(void)
{
	//deinit env

	/*uninstall apk*/
    uninstall_apk("com.fish.phonetest3");
	
	/*deinit socket*/
	socket_monkey_deinit();
}

bool install_apk(char* apkname)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//tell monkey runner to install test apk 
	//through monkey runner socket (localhost 8001)
	//send "install" by socket
	
	assert(NULL != apkname);

	send_buffer_init(&pbuf,&length);
	add_cmd("install",7,pbuf,&length);
	add_elem(apkname,strlen(apkname),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"install",7,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool uninstall_apk(char* apkname)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//tell monkey runner to uninstall test apk 
	//through monkey runner socket (localhost 8001)
	//send "uninstall" by socket
	assert(NULL != apkname);

	send_buffer_init(&pbuf,&length);
	add_cmd("uninstall",9,pbuf,&length);
	add_elem(apkname,strlen(apkname),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"uninstall",9,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool touch(int x,int y)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	char tranbuf[5] = {0};
	bool ret = false;
	int parbegin = 0;

	//through monkey socket socket (localhost 8001)
	//send "touch,x,y" by socket
	send_buffer_init(&pbuf,&length);
	add_cmd("touch",5,pbuf,&length);
	parbegin = length;
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",x);
	add_elem(tranbuf,4,parbegin,pbuf,&length);
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",y);
	add_elem(tranbuf,4,parbegin,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"touch",5,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool drag(int startx, int starty, int endx, int endy)
{	
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	char tranbuf[5] = {0};
	bool ret = false;
	int parbegin = 0;

	//through monkey socket socket (localhost 8001)
	//send "drag,x1,y1,x2,y2" by socket

	send_buffer_init(&pbuf,&length);
	add_cmd("drag",4,pbuf,&length);
	parbegin = length;
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",startx);
	add_elem(tranbuf,4,parbegin,pbuf,&length);
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",starty);
	add_elem(tranbuf,4,parbegin,pbuf,&length);
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",endx);
	add_elem(tranbuf,4,parbegin,pbuf,&length);
	memset(tranbuf,0,5);
	sprintf(tranbuf,"%4d",endy);
	add_elem(tranbuf,4,parbegin,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"drag",4,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool snap(char * pic_name)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8001)
	//send "snap,name" by socket

	assert(NULL != pic_name);

	send_buffer_init(&pbuf,&length);
	add_cmd("snap",4,pbuf,&length);
	add_elem(pic_name,strlen(pic_name),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"snap",4,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

/*
MENU
BACK
HOME
SEARCH
CAMERA
VOLUP
VOLDOWN
POWER
*/

bool key(char * keyvalue)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8001)
	//send "key,keyvalue" by socket

	assert(NULL != keyvalue);

	send_buffer_init(&pbuf,&length);
	add_cmd("key",3,pbuf,&length);
	add_elem(keyvalue,strlen(keyvalue),length,pbuf,&length);	

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"key",3,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;

}

bool adbcmd(char * cmd)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8001)
	//send "adbcmd,cmd" by socket

	assert(NULL != cmd);

	send_buffer_init(&pbuf,&length);
	add_cmd("adbcmd",6,pbuf,&length);
	add_elem(cmd,strlen(cmd),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"adbcmd",6,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool putfile(char * phonefile,char* pcfile)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8001)
	//send "putfile,phonefile,pcfile" by socket

	assert((NULL != phonefile) && (NULL != pcfile));

	send_buffer_init(&pbuf,&length);
	add_cmd("putfile",7,pbuf,&length);
	add_elem(phonefile,strlen(phonefile),length,pbuf,&length);
	add_elem(pcfile,strlen(pcfile),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"putfile",7,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool getfile(char * phonefile,char* pcfile)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8001)
	//send "getfile,phonefile,pcfile" by socket

	assert((NULL != phonefile) && (NULL != pcfile));

	send_buffer_init(&pbuf,&length);
	add_cmd("getfile",7,pbuf,&length);
	add_elem(phonefile,strlen(phonefile),length,pbuf,&length);
	add_elem(pcfile,strlen(pcfile),length,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_MONKEY))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"getfile",7,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

bool get_device_info(void)
{
	char * pbuf = NULL;
	int length = 0;
	char* rspbuf = NULL;
	int rsplen = 0;
	bool ret = false;

	//through monkey socket socket (localhost 8003)
	//send "getDeviceInfo" by socket

	send_buffer_init(&pbuf,&length);
	add_cmd("getDeviceInfo",13,pbuf,&length);

	if(socket_send_cmd_recv_rsp(pbuf,length,&rspbuf,&rsplen,E_SOC_APK))
	{
		int parse_len = 0;
		char * ppar = NULL;
		int parlen = 0;

		assert (NULL != rspbuf);

		if(check_rsp_data_valid(rspbuf,rsplen,"getDeviceInfo",13,&parse_len))
		{
			if (1 == get_elem_len(rspbuf,&parse_len))
			{
				get_parameter(&parlen,&ppar,rspbuf,&parse_len);
				if(0 == strncmp(ppar,"PASS",parlen))
				{
					ret = true;
				}
				else if(0 == strncmp(ppar,"FAIL",parlen))
				{
					ret = false;
				}
				else
				{
					assert(0);
				}			
			}
			else
			{
				ret = false;
			}

			free(ppar);
			ppar = NULL;
		}
		free(rspbuf);
		rspbuf = NULL;
	}
	return ret;
}

char * get_sn_or_imsi()
{
	//through apk socket (localhost 8003)
	//send "imei" by socket	
	return NULL;
}

char* get_mnc()
{
	//GET operator (eg  CMCC)	
	//through apk socket (localhost 8003)
	//send "mnc" by socket	
	return NULL;
}

int get_sensors()
{
	//TBD , only suggest 
	//through apk socket (localhost 8003)
	//send "sensor" by socket	
	//barney number
	//XXXX XXXX XXXX XXX1  	L-sensor
	//   ...................
	//XXXX XXXX XXXX XX1X  	P-sensor
	return 0;
}

void test_p_sensor()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "psensor" by socket	
}

void test_l_sensor()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "lsensor" by socket	
}

void test_wifi()
{
	//TBD , only suggest	
	//through apk socket (localhost 8003)
	//send "wifi" by socket		
}

void test_bt()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "bt" by socket		
}

void test_fm()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "fm" by socket		
}

void test_gps()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "gps" by socket		
}

void test_cmmb()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "cmmb" by socket		
}

void test_camera_f()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "cameraf" by socket		
}

void test_camera_b()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "camerab" by socket		
}

void test_flash_light()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "flash" by socket		
}

void test_sim()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "sim" by socket		
}

void test_call()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "call" by socket		
}

void test_volume_up()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "volumeup" by socket		
}

void test_volume_down()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "volumedown" by socket		
}

void test_charger()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "charger" by socket		
}

void test_usb()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "usb" by socket		
}

void test_battary()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "battary" by socket		
}

void test_sd_card()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "sd" by socket		
}

void test_mute_key()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "mute" by socket		
}

void test_camera_key()
{
	//TBD , only suggest
	//through apk socket (localhost 8003)
	//send "camkey" by socket		
}

void vibrator(int time)
{
	//through apk socket (localhost 8003)
	//send "vib,time" by socket	
}

void test_rgblight()
{
	//through apk socket (localhost 8003)
	//send "rgb" by socket		
}

void test_keylight()
{
	//through apk socket (localhost 8003)
	//send "key" by socket		
}

void test_lcd_backlightt()
{
	//through apk socket (localhost 8003)
	//send "lcdlight" by socket		
}

void test_sound()
{
	//sound  mic recever speaker	
	//through apk socket (localhost 8003)
	//send "sound" by socket	
}

int main(int argc, char *argv[])
{	
	//for test the env
	int i = 0;

	env_init();
//	uninstall_apk("com.fish.phonetest3");
//	install_apk("PhoneTest3.apk");
//	uninstall_apk("com.fish.phonetest3");
//	install_apk("PhoneTest3.apk");
	get_device_info();

	drag(0,400,320,400);
	drag(0,400,320,400);
	drag(320,400,0,400);
	drag(320,400,0,400);
	drag(320,400,0,400);

	for(i=0;i<100;i++)
	{
		char namepic[5] = {0};
		sprintf(namepic,"%d",i);
		snap((char*)namepic);
	}
	touch(160,240);
	key("MENU");
	key("BACK");
	key("MENU");
	key("BACK");
	key("SEARCH");
	key("HOME");
	key("VOLUP");
	key("VOLDOWN");
	key("CAMERA");
	key("HOME");
	key("POWER");
	key("POWER");
	env_deinit();

	return 0;
	
}